/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.bs.util;


import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Bone
 */
public class RefletorDeCampoBean {

    private static Boolean definirDatasParaHora = false;
    private static String padraoDeDatas = "dd/MM/yyyy";
    private static String padraoDeHoras = "HH:MM";

    public static Object get(Object objeto, String campo) {
        ObjetoParaReflexao ref = getObjetoParaReflexao(objeto, campo);
        if(ref.getCampo() == null){
            System.out.println("Houve algum problema ao carregar o objeto para reflexão.\n" +
                    "Esse erro é calsado geralmente quando o objeto informado nulo.");
            return "";
        }
        Object obj = ref.getObjeto();
        Field f = ref.getCampo();
        f.setAccessible(true);

        Object r;
        try {
            r = f.get(obj);
            if (r == null) {
                return "";
            } else {
                if (r instanceof Date || r instanceof java.sql.Date) {
                    if (definirDatasParaHora) {
                        SimpleDateFormat fmt = new SimpleDateFormat(padraoDeHoras);
                        return fmt.format(r);
                    } else {
                        SimpleDateFormat fmt = new SimpleDateFormat(padraoDeDatas);
                        return fmt.format(r);
                    }

                }
                return r;
            }
        } catch (Exception ex) {
            Logger.getLogger(RefletorDeCampoBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
        /*try {
        Field ret = null;
        Object obj = objeto;
        String copiaCampo = new String(campo);
        do {
        if (copiaCampo.contains(".")) {
        String c = copiaCampo.substring(0, copiaCampo.indexOf("."));
        copiaCampo = copiaCampo.replace(c + ".", "");
        ret = obj.getClass().getDeclaredField(c);
        ret.setAccessible(true);
        obj = ret.get(obj);
        } else {
        Field f = obj.getClass().getDeclaredField(copiaCampo);
        f.setAccessible(true);
        Object r = f.get(obj);
        if (r == null) {
        return "";
        } else {
        return r;
        }
        }
        } while (true);
        } catch (Exception ex) {
        Logger.getLogger(RefletorDeCampoBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;*/
    }

    public static void set(Object objeto, String campo, Object novoValor) {
        ObjetoParaReflexao ref = getObjetoParaReflexao(objeto, campo);
        if(ref.getCampo() == null){
            System.out.println("Houve algum problema ao carregar o objeto para reflexão.\n" +
                    "Esse erro é calsado geralmente quando o objeto informado nulo.");
            return;
        }
        Field f = ref.getCampo();
        Object obj = ref.getObjeto();
        Class tipoField =  f.getType();
        f.setAccessible(true);
        String valorString = String.valueOf(novoValor);
        try {
            if(novoValor instanceof String){
                if(novoValor.equals("")){
                    return;
                }
            }
            if(valorString.contains("R$") || valorString.contains("%")){
                valorString = valorString.replaceAll("[^0-9|^.]", "");
                novoValor = valorString;
            }
            if (tipoField == Date.class) {
                SimpleDateFormat fmt = new SimpleDateFormat(padraoDeDatas);
                f.set(obj, fmt.parse(String.valueOf(novoValor)));
                return;
            }
            if(novoValor.equals("")){
                novoValor = "0";
            }
            if (tipoField == Integer.class || tipoField == int.class) {

                String s = String.valueOf(novoValor);
                f.set(obj, Integer.valueOf(s));
                return;
            }
            if (tipoField == Long.class || tipoField == long.class) {
                f.set(obj, Long.valueOf(String.valueOf(novoValor)));
                return;
            }
            if (tipoField == Double.class || tipoField == double.class) {
                f.set(obj, Double.valueOf(String.valueOf(novoValor)));
                return;
            }
            if (tipoField == BigDecimal.class) {
                f.set(obj, BigDecimal.valueOf(Double.valueOf(String.valueOf(novoValor))));
                return;
            }
            f.set(obj, novoValor);
        } catch (Exception ex) {
            Logger.getLogger(RefletorDeCampoBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        /*try {
        Field ret = null;
        Object obj = objeto;
        String copiaCampo = new String(campo);
        do {
        if (copiaCampo.contains(".")) {
        String c = copiaCampo.substring(0, copiaCampo.indexOf("."));
        copiaCampo = copiaCampo.replace(c + ".", "");
        ret = obj.getClass().getDeclaredField(c);
        ret.setAccessible(true);
        obj = ret.get(obj);
        } else {

        Field f = obj.getClass().getDeclaredField(copiaCampo);
        f.setAccessible(true);
        if (f.getType() == Integer.class) {
        String s = String.valueOf(novoValor);
        f.set(obj, Integer.valueOf(s));
        return;
        }
        if (f.getType() == Long.class) {
        f.set(obj, Long.valueOf(String.valueOf(novoValor)));
        return;
        }
        if (f.getType() == BigDecimal.class) {
        f.set(obj, BigDecimal.valueOf(Double.valueOf(String.valueOf(novoValor))));
        return;
        }
        if (f.getType() == Date.class) {
        f.set(obj, Date.parse(String.valueOf(novoValor)));
        return;
        }
        f.set(obj, novoValor);
        return;
        }
        } while (true);
        } catch (Exception ex) {
        Logger.getLogger(RefletorDeCampoBean.class.getName()).log(Level.SEVERE, null, ex);
        }*/
    }

    private static ObjetoParaReflexao getObjetoParaReflexao(Object objeto, String campo) {
        try {
            Field ret = null;
            Object obj = objeto;
            String copiaCampo = new String(campo);
            do {
                if (copiaCampo.contains(".")) {
                    String c = copiaCampo.substring(0, copiaCampo.indexOf("."));
                    copiaCampo = copiaCampo.replace(c + ".", "");
                    ret = obj.getClass().getDeclaredField(c);
                    ret.setAccessible(true);
                    obj = ret.get(obj);
                } else {
                    ObjetoParaReflexao ref = new ObjetoParaReflexao();
                    if(obj== null){
                        return ref;
                    }
                    ref.setCampo(obj.getClass().getDeclaredField(copiaCampo));
                    ref.setObjeto(obj);
                    return ref;
                }
            } while (true);
        } catch (Exception ex) {
            Logger.getLogger(RefletorDeCampoBean.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    public static Boolean getDefinirDatasParaHora() {
        return definirDatasParaHora;
    }

    public static void setDefinirDatasParaHora(Boolean definirDatasParaHora) {
        RefletorDeCampoBean.definirDatasParaHora = definirDatasParaHora;
    }

    public static String getPadraoDeDatas() {
        return padraoDeDatas;
    }

    public static void setPadraoDeDatas(String padraoDeDatas) {
        RefletorDeCampoBean.padraoDeDatas = padraoDeDatas;
    }

    public static String getPadraoDeHoras() {
        return padraoDeHoras;
    }

    public static void setPadraoDeHoras(String padraoDeHoras) {
        RefletorDeCampoBean.padraoDeHoras = padraoDeHoras;
    }
}
